import { v4 as uuidv4 } from "uuid";
const WEBSOCKET_URL = "ws://localhost:3000/websocket";

const commonExec = <T extends Object>(url: string) => {
  return async (param?: T) => {
    try {
      const queryStr = new URLSearchParams(
        Object.entries(param ?? {})
      ).toString();
      const res = await fetch(
        `${url}?${queryStr}&time=${new Date().getTime() + uuidv4()}`
      );
      const data = await res.json();
      if (data.code !== 0) {
        console.log(`code: ${data.code}, msg: ${data.msg}`);
      }
      return data.msg ?? "";
    } catch (err) {
      console.log(err);
    }
  };
};

const commonGet = <I extends Object, O extends Object>(url: string) => {
  return async (param?: I): Promise<O[]> => {
    try {
      const queryStr = new URLSearchParams(
        Object.entries(param ?? {})
      ).toString();
      const res = await fetch(`${url}?${queryStr}`);
      const data = await res.json();
      if (data.code !== 0) {
        console.log(`code: ${data.code}, msg: ${data.msg}`);
      }
      return data.data ?? [];
    } catch (err) {
      console.log(err);
      return [];
    }
  };
};

interface TrainParams {
  expName: string;
  totalTimesteps: number;
  learningRate: number;
  bufferSize: number;
  gamma: number;
  batchSize: number;
  startEpsilon: number;
  endEpsilon: number;
  explorationFraction: number;
  learningStarts: number;
}
const initTrainParams = {
  expName: "train",
  totalTimesteps: 500001,
  learningRate: 2.5e-4,
  bufferSize: 1000,
  gamma: 0.99,
  batchSize: 8,
  startEpsilon: 1,
  endEpsilon:0.05,
  explorationFraction: 0.5,
  learningStarts: 10000,
};
interface TestParams {
  dataset: string;
}
const initTestParams = {
  dataset: "RSOD",
};
const runTrain = commonExec<TrainParams>("/train/run");
const runTest = commonExec<TestParams>("/test/run");
const stopTrain = commonExec("/train/stop");
const stopTest = commonExec("/test/stop");
const getDatasetNameList = commonGet<object, string>("/dataset/name-list");
const getCvmodelNameList = commonGet<object, string>("/cvmodel/name-list");
const getStatus = async function () {
  const res = await fetch("/status");
  const { status } = await res.json();
  return status;
};

export {
  WEBSOCKET_URL,
  initTrainParams,
  initTestParams,
  runTrain,
  runTest,
  stopTrain,
  stopTest,
  getDatasetNameList,
  getCvmodelNameList,
  getStatus,
};
